﻿using StockMarketTool.Helper;
using StockMarketTool.HotKey;
using StockMarketTool.ViewModel;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Configuration;
using System.Threading;
using System.Timers;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Animation;
using Timer = System.Timers.Timer;

namespace StockMarketTool
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        private MainViewModel viewmodel = null;

        /// <summary>
        /// 当前窗口句柄
        /// </summary>
        private IntPtr m_Hwnd = new IntPtr();

        /// <summary>
        /// 记录快捷键注册项的唯一标识符
        /// </summary>
        private Dictionary<EHotKeySetting, int> m_HotKeySettings = new Dictionary<EHotKeySetting, int>();


        //鼠标状态 true为进入窗体 false为离开窗体
        private bool IsMouseEnter = false;
        //计时器 通过win32api实时获取鼠标位置
        private Timer timer;

        private double _hideSize = 10;
        
        private bool blnTopHide;

        public MainWindow()
        {
            InitializeComponent();
            this.viewmodel = new MainViewModel();
            this.DataContext = this.viewmodel;
            this.Loaded += MainWindow_Loaded;
            this.Closing += MainWindow_Closing;
            timer = new Timer();
            timer.Interval = 500;
            timer.Elapsed += Timer_Elapsed;

            string PreLocation = AppSettingHelper.GetValue<string>("PreLocation", "");
            if (!String.IsNullOrWhiteSpace(PreLocation))//上一次退出的位置不为空，定位过去
            {
                try
                {
                    Point point = new Point();
                    point = Point.Parse(PreLocation);
                    this.WindowStartupLocation = WindowStartupLocation.Manual;
                    this.Left = point.X;
                    this.Top = point.Y;
                }
                catch
                {
                    LogHelper.Log("读取上一次退出的位置出错，位置：" + PreLocation);
                }

            }
        }

        private void Timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            Dispatcher.BeginInvoke(new Action(() =>
            {
                procUpdateLocation();
            }
            ));

        }

        private void procUpdateLocation()
        {
            if (this.Top > SystemParameters.WorkArea.Height - this.ActualHeight)
            {
                this.Top = SystemParameters.WorkArea.Height - this.ActualHeight;
            }
            Point point = PointToScreen(Mouse.GetPosition(this));//获取鼠标相对桌面的位置

            //true:鼠标在窗体内部;false:鼠标离开窗体
            IsMouseEnter = (point.X >= this.Left && point.X <= this.Left + this.Width + 30 && point.Y >= this.Top && point.Y <= this.Top + this.Height + 30);
            if (this.Top <= 0)
            {
                if (blnTopHide)
                {
                    if (point.X >= this.Left && point.X <= this.Left + this.Width)
                    {
                        if (point.Y <= 0)
                        {
                            TranslateTransform tt = new TranslateTransform();
                            DoubleAnimation da = new DoubleAnimation();
                            Duration duration = new Duration(TimeSpan.FromSeconds(0.6));//动画时间
                            this.RenderTransform = tt;//设置按钮的转换效果
                            tt.Y = _hideSize - this.Height;
                            da.To = 0;
                            da.SpeedRatio = 2;
                            da.Duration = duration;
                            tt.BeginAnimation(TranslateTransform.YProperty, da);
                            Thread.Sleep(100);
                            blnTopHide = false;//把窗体状态设置为显示 
                        }
                    }
                    return;
                }
                else
                {
                    if (this.Top <= 0 && !IsMouseEnter)
                    {
                        this.Top = 0;
                        TranslateTransform tt = new TranslateTransform();
                        DoubleAnimation da = new DoubleAnimation();
                        Duration duration = new Duration(TimeSpan.FromSeconds(0.6));//动画时间
                        this.RenderTransform = tt;//设置按钮的转换效果
                        tt.Y = 0;
                        da.To = _hideSize - this.Height;
                        da.SpeedRatio = 2;
                        //da.By = 0.5;
                        da.Duration = duration;
                        tt.BeginAnimation(TranslateTransform.YProperty, da);
                        System.Threading.Thread.Sleep(300);
                        blnTopHide = true;
                    }
                    return;
                }
            }
            else if (this.Left <= 0)
            {
                if (blnTopHide)
                {
                    if (point.Y >= this.Top && point.Y <= this.Top + this.Height)
                    {
                        TranslateTransform tt = new TranslateTransform();
                        DoubleAnimation da = new DoubleAnimation();
                        Duration duration = new Duration(TimeSpan.FromSeconds(0.6));//动画时间
                        this.RenderTransform = tt;//设置按钮的转换效果
                        tt.X = _hideSize - this.Width;
                        da.To = 0;
                        da.SpeedRatio = 2;
                        da.Duration = duration;
                        tt.BeginAnimation(TranslateTransform.XProperty, da);
                        System.Threading.Thread.Sleep(100);
                        blnTopHide = false;//把窗体状态设置为显示 
                    }
                }
                else
                {
                    Point b = Mouse.GetPosition(this);//获取鼠标相对窗口的位置
                    if (this.Left <= 0 && !IsMouseEnter)
                    {
                        this.Left = 0;
                        TranslateTransform tt = new TranslateTransform();
                        DoubleAnimation da = new DoubleAnimation();
                        Duration duration = new Duration(TimeSpan.FromSeconds(0.6));//动画时间
                        this.RenderTransform = tt;//设置按钮的转换效果
                        tt.X = 0;
                        da.To = _hideSize - this.Width;
                        da.SpeedRatio = 2;
                        da.Duration = duration;
                        tt.BeginAnimation(TranslateTransform.XProperty, da);
                        System.Threading.Thread.Sleep(300);
                        blnTopHide = true;
                    }
                    return;
                }
            }
            else if (this.Left + this.Width >= SystemParameters.PrimaryScreenWidth)
            {
                if (blnTopHide)
                {
                    if (point.Y >= this.Top && point.Y <= this.Top + this.Height)
                    {
                        TranslateTransform tt = new TranslateTransform();
                        DoubleAnimation da = new DoubleAnimation();
                        Duration duration = new Duration(TimeSpan.FromSeconds(0.6));//动画时间
                        this.RenderTransform = tt;//设置按钮的转换效果
                        tt.X = this.Width - _hideSize;
                        da.To = 0;
                        da.SpeedRatio = 2;
                        da.Duration = duration;
                        tt.BeginAnimation(TranslateTransform.XProperty, da);
                        System.Threading.Thread.Sleep(100);
                        blnTopHide = false;//把窗体状态设置为显示 
                    }
                }
                else
                {
                    Point b = Mouse.GetPosition(this);//获取鼠标相对窗口的位置
                    if (!IsMouseEnter)
                    {
                        this.Left = SystemParameters.PrimaryScreenWidth - this.Width;
                        //this.Top = 0 - this.Height;//隐藏窗体
                        TranslateTransform tt = new TranslateTransform();
                        DoubleAnimation da = new DoubleAnimation();
                        Duration duration = new Duration(TimeSpan.FromSeconds(0.6));//动画时间
                        this.RenderTransform = tt;//设置按钮的转换效果
                        tt.X = 0;
                        da.To = this.Width - _hideSize;
                        da.SpeedRatio = 2;
                        da.Duration = duration;
                        tt.BeginAnimation(TranslateTransform.XProperty, da);
                        System.Threading.Thread.Sleep(300);
                        blnTopHide = true;
                    }
                }
            }
            else
            {
                if (blnTopHide)
                {
                    TranslateTransform tt = new TranslateTransform();
                    DoubleAnimation da = new DoubleAnimation();
                    Duration duration = new Duration(TimeSpan.FromSeconds(0.6));//动画时间
                    this.RenderTransform = tt;//设置按钮的转换效果
                    tt.X = _hideSize - this.Width;
                    da.To = 0;
                    da.SpeedRatio = 2;
                    da.Duration = duration;
                    tt.BeginAnimation(TranslateTransform.XProperty, da);
                    System.Threading.Thread.Sleep(100);
                    blnTopHide = false;//把窗体状态设置为显示 
                }
            }
        }

        private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            timer?.Stop();
            this.viewmodel.SaveConfig();

            Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            config.AppSettings.Settings["PreLocation"].Value = this.Left.ToString() + "," + this.Top.ToString();
            config.Save();
            LogHelper.Log("退出");
        }

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            LogHelper.Log("已启动");
            IntPtr hwnd = new WindowInteropHelper(this).Handle;
            HotKeyManager.IntSetWindowLong(hwnd, (-20), 0x80);

            this.timer.Start();

            HotKeySettingsManager.Instance.RegisterGlobalHotKeyEvent += Instance_RegisterGlobalHotKeyEvent;
        }
        /// <summary>
        /// WPF窗体的资源初始化完成，并且可以通过WindowInteropHelper获得该窗体的句柄用来与Win32交互后调用
        /// </summary>
        /// <param name="e"></param>
        protected override void OnSourceInitialized(EventArgs e)
        {
            base.OnSourceInitialized(e);
            // 获取窗体句柄
            m_Hwnd = new WindowInteropHelper(this).Handle;
            HwndSource hWndSource = HwndSource.FromHwnd(m_Hwnd);
            // 添加处理程序
            if (hWndSource != null) hWndSource.AddHook(WndProc);
        }
        /// <summary>
        /// 所有控件初始化完成后调用
        /// </summary>
        /// <param name="e"></param>
        protected override void OnContentRendered(EventArgs e)
        {
            base.OnContentRendered(e);
            // 注册热键
            InitHotKey();
        }
        /// <summary>
        /// 通知注册系统快捷键事件处理函数
        /// </summary>
        /// <param name="hotKeyModelList"></param>
        /// <returns></returns>
        private bool Instance_RegisterGlobalHotKeyEvent(ObservableCollection<HotKeyModel> hotKeyModelList)
        {
            return InitHotKey(hotKeyModelList);
        }

        /// <summary>
        /// 初始化注册快捷键
        /// </summary>
        /// <param name="hotKeyModelList">待注册热键的项</param>
        /// <returns>true:保存快捷键的值；false:弹出设置窗体</returns>
        private bool InitHotKey(ObservableCollection<HotKeyModel> hotKeyModelList = null)
        {
            var list = hotKeyModelList ?? HotKeySettingsManager.Instance.LoadDefaultHotKey();
            // 注册全局快捷键
            string failList = HotKeyHelper.RegisterGlobalHotKey(list, m_Hwnd, out m_HotKeySettings);
            if (string.IsNullOrEmpty(failList))
                return true;
            MessageBox.Show(string.Format("无法注册下列快捷键\n\r{0}", failList));

            return true;
        }

        /// <summary>
        /// 窗体回调函数，接收所有窗体消息的事件处理函数
        /// </summary>
        /// <param name="hWnd">窗口句柄</param>
        /// <param name="msg">消息</param>
        /// <param name="wideParam">附加参数1</param>
        /// <param name="longParam">附加参数2</param>
        /// <param name="handled">是否处理</param>
        /// <returns>返回句柄</returns>
        private IntPtr WndProc(IntPtr hWnd, int msg, IntPtr wideParam, IntPtr longParam, ref bool handled)
        {
            switch (msg)
            {
                case HotKeyManager.WM_HOTKEY:
                    int sid = wideParam.ToInt32();
                    if (sid == m_HotKeySettings[EHotKeySetting.显示或隐藏])
                    {
                        Dispatcher.Invoke(() =>
                        {
                            if (this.Opacity == 1)
                                this.Opacity = 0.1;
                            else
                                this.Opacity = 1;
                        });
                    }
                    else if (sid == m_HotKeySettings[EHotKeySetting.复位])
                    {
                        Dispatcher.Invoke(() =>
                        {
                            this.Left = SystemParameters.PrimaryScreenWidth / 2;
                            this.Top = SystemParameters.PrimaryScreenHeight / 2;
                            procUpdateLocation();
                        });
                    }
                    handled = true;
                    break;
            }
            return IntPtr.Zero;
        }
        
        private void Border_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (e.ClickCount == 2 && e.LeftButton == MouseButtonState.Pressed)
            {
                try
                {
                    Setting setting = Setting.GetInstance(this.viewmodel);
                    if (this.Top - setting.Height <= 0)
                    {
                        setting.Top = this.Top + this.Height;
                    }
                    else if (this.Top + this.Height + setting.Height > SystemParameters.WorkArea.Height)
                    {
                        setting.Top = this.Top - setting.Height;
                    }
                    else
                    {
                        setting.Top = this.Top + this.Height;
                    }
                    if (this.Left + setting.Width > SystemParameters.PrimaryScreenWidth)
                    {
                        setting.Left = SystemParameters.PrimaryScreenWidth - setting.Width;
                    }
                    else
                    {
                        setting.Left = this.Left;
                    }
                    setting.Show();
                    setting.Activate();
                }
                catch (Exception ex)
                {
                    LogHelper.LogError(ex, "打开设置窗口异常");
                }
            }
        }

        private void ExitItem_Click(object sender, RoutedEventArgs e)
        {
            Application.Current.Shutdown();
        }

        private void Window_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                this.DragMove();
            }
        }

    }
}
